package com.example.demo.common;

import com.alibaba.fastjson.JSONObject;
import com.example.demo.common.constant.ResultCode;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

@Data
@ApiModel(value = "接口返回值结构")
public class Result {
    /*@ApiModelProperty("记录ID：用于日志定位")
    public String traceId;*/

    @ApiModelProperty("标识符：1成功，0警告，-1参数校验异常，-2身份验证异常，-3数据异常，-4业务逻辑异常, -8未定义异常，-9系统异常")
    public Integer code;

    @ApiModelProperty("异常种类代码")
    public Integer type;

    @ApiModelProperty("提示信息：正常时返回【成功】，警示时返回【WARN:XXX】，异常时返回【ERROR:XXX】")
    public String message;

    @ApiModelProperty("结果值：JSON结构")
    public JSONObject data;

    /*public String toString() {
        return "{\"traceId\":\"" + MDC.get("traceId") + "\",\"code\":" + this.code.toString() + (this.type != null ? ",\"type\":" + this.type.toString() : "") + ",\"message\":\"" + this.message + "\"" + (this.data != null ? ",\"data\":" + this.data.toJSONString() : "") + "}";
    }*/

    public String toString() {
        return "{\"code\":" + this.code.toString() + (this.type != null ? ",\"type\":" + this.type : "") + ",\"message\":\"" + this.message + "\"" + (this.data != null ? ",\"data\":" + this.data.toJSONString() : "") + "}";
    }

    public void put(String key, Object value) {
        if (this.data == null) {
            this.data = new JSONObject();
        }
        this.data.put(key, value);
    }

    public Object get(String key) {
        return this.data.get(key);
    }

    public String getString(String key) {
        return this.data.getString(key);
    }

    public Result ok() {
        this.init(1, ResultCode.SUCCESS);
        return this;
    }

    public Result error(String message) {
        this.init(-8, null, message);
        return this;
    }

    public Result error(ResultCode resultCode) {
        int code = resultCode.getCode();
        if (code > 1000 && code < 2000) {
            this.setValidError(resultCode);
        } else if (code > 2000 && code < 3000) {
            this.setVisitError(resultCode);
        } else if (code > 3000 && code < 4000) {
            this.setDataError(resultCode);
        } else if (code > 4000 && code < 5000) {
            this.setBusinessError(resultCode);
        } else if (code > 9000 && code < 10000) {
            this.setSystemError(resultCode);
        } else if (code == 0) {
            this.warn(resultCode);
        } else {
            this.error("未定义异常");
        }

        return this;
    }

    public Result error(String message, ResultCode resultCode) {
        if (resultCode != null) {
            int code = resultCode.getCode();
            if (code == 1999) {
                this.setValidError(message);
            } else if (code == 2999) {
                this.setVisitError(message);
            } else if (code == 3999) {
                this.setDataError(message);
            } else if (code == 4999) {
                this.setBusinessError(message);
            } else if (code == 9999) {
                this.setSystemError(message);
            } else if (code == 0) {
                this.warn(message);
            } else {
                this.error("异常标志错误");
            }
        } else {
            this.error(message);
        }

        return this;
    }

    public void warn(String message) {
        this.init(0, ResultCode.WARN, message);
    }

    public void warn(ResultCode resultCode) {
        this.init(0, resultCode);
    }

    public void setValidError(String message) {
        this.init(-1, null, message);
    }

    public void setValidError(String message, ResultCode resultCode) {
        this.init(-1, resultCode, message);
    }

    public void setValidError(ResultCode resultCode) {
        this.init(-1, resultCode);
    }

    public void setVisitError(String message) {
        this.init(-2, null, message);
    }

    public void setVisitError(ResultCode resultCode) {
        this.init(-2, resultCode);
    }

    public void setDataError(String message) {
        this.init(-3, null, message);
    }

    public void setDataError(String message, ResultCode resultCode) {
        this.init(-3, resultCode, message);
    }

    public void setDataError(ResultCode resultCode) {
        this.init(-3, resultCode);
    }

    public void setBusinessError(String message) {
        this.init(-4, null, message);
    }

    public void setBusinessError(String message, ResultCode resultCode) {
        this.init(-4, resultCode, message);
    }

    public void setBusinessError(ResultCode resultCode) {
        this.init(-4, resultCode);
    }

    public void setSystemError(String message) {
        this.init(-9, null, message);
    }

    public void setSystemError(ResultCode resultCode) {
        this.init(-9, resultCode);
    }

    private void init(Integer code, ResultCode resultCode, String message) {
        //this.traceId = MDC.get("traceId");
        this.code = code;
        this.type = resultCode != null ? resultCode.getCode() : null;
        if (this.code == 1) {
            this.message = message;
        } else if (this.code == 0) {
            this.message = "WARN:" + message;
        } else {
            this.message = "ERROR:" + message;
        }
    }

    private void init(Integer code, ResultCode resultCode) {
        //this.traceId = MDC.get("traceId");
        this.code = code;
        this.type = resultCode.getCode();
        if (this.type == 1) {
            this.message = resultCode.getMessage();
        } else if (this.type == 0) {
            this.message = "WARN:" + resultCode.getMessage();
        } else {
            this.message = "ERROR:" + resultCode.getMessage();
        }
    }
}
